package com.bdqn.dao;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.IOException;
import java.io.InputStream;
import java.sql.*;
import java.util.Properties;

/**
 * BaseDao 数据库操作的基础方法
 *
 * @author LILIBO
 * @since 2022-04-26
 */
public class BaseDao {

    private static Logger logger = LogManager.getLogger(BaseDao.class);

    /**
     * 配置文件所在位置
     */
    private static String config = "database.properties";

    private static String driver; // 数据库驱动
    private static String url; // 数据库连接字符串
    private static String username; // 账号
    private static String password; // 密码

    /**
     * 类加载时执行初始化
     */
    static {
        // 初始化配置文件
        initProperties();
        // 初始化加载数据库驱动
        initDatabaseDriver();
    }

    /**
     * 初始化配置文件
     */
    private static void initProperties() {
        // 声明Properties配置文件对象
        Properties properties = new Properties();
        // 获取配置文件输入流对象
        InputStream input = BaseDao.class.getClassLoader().getResourceAsStream(config);
        try {
            // 加载配置文件
            properties.load(input);
            driver = properties.getProperty("driver", "com.mysql.cj.jdbc.Driver");
            url = properties.getProperty("url", "jdbc:mysql://localhost:3306/demo?serverTimezone=GMT-8");
            username = properties.getProperty("username", "root");
            password = properties.getProperty("password", "lilibo");
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        logger.debug("-------- 初始化配置文件成功 --------");
    }

    /**
     * 初始化加载数据库驱动
     */
    private static void initDatabaseDriver() {
        try {
            Class.forName(driver);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
        logger.debug("-------- 加载数据库驱动成功 --------");
    }

    /**
     * 获得数据库连接对象
     *
     * @return 数据库连接对象
     */
    public static Connection getConnection() {
        Connection conn = null;
        try {
            // 通过配置文件读取到的参数获取连接对象
            conn = DriverManager.getConnection(url, username, password);
        } catch (SQLException e) {
            e.printStackTrace();
        }
        logger.debug("-------- 获取数据库连接成功 --------");
        return conn;
    }

    /**
     * 释放资源，关闭数据库连接
     *
     * @param rs 数据库结果集对象
     * @param stmt 数据库操作对象
     * @param conn 数据库连接对象
     */
    public static void closeAll(ResultSet rs, Statement stmt, Connection conn) {
        if (rs != null) {
            try {
                // 关闭数据库结果集对象
                rs.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (stmt != null) {
            try {
                // 关闭数据库操作对象
                stmt.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        if (conn != null) {
            try {
                // 关闭数据库连接对象
                conn.close();
            } catch (SQLException e) {
                throw new RuntimeException(e);
            }
        }
        logger.debug("-------- 关闭数据库连接成功 --------");
    }

    /**
     * 通用的增删改方法
     *
     * @param sql 需要执行的SQL语句
     * @param params SQL语句问号对应参数
     * @return 执行受影响行数
     */
    public static int executeUpdate(String sql, Object[] params) {
        // 需要返回的结果
        int result = 0;

        // 获取数据库连接
        Connection conn = BaseDao.getConnection();
        PreparedStatement pstmt = null;
        // 创建数据库操作对象
        try {
            // String sql = "insert into student(studentNo,loginPwd,studentName,sex,gradeID) values(?,?,?,?,?)";
            logger.debug("SQL: " + sql);
            logger.debug("Params: ");
            pstmt = conn.prepareStatement(sql);
            // 对参数进行处理
            if (params != null) {
                for (int i = 0; i < params.length; i++) {
                    pstmt.setObject(i + 1, params[i]);
                    logger.debug("?" + (i + 1) + " = " + params[i]);
                }
            }
            // 执行SQL语句
            result = pstmt.executeUpdate();
            logger.debug("-------- 执行数据库操作成功 -------- Result: " + result);
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            // 释放资源关闭连接
            BaseDao.closeAll(null, pstmt, conn);
        }
        return result;
    }
}
